home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / RollOverButton.java < prev    next >
Text File  |  1998-08-27  |  36KB  |  1,252 lines

  1. package symantec.itools.awt;
  2.  
  3. import java.awt.Dimension;
  4. import java.awt.Graphics;
  5. import java.awt.Image;
  6. import java.awt.MediaTracker;
  7. import java.awt.Toolkit;
  8. import java.net.URL;
  9. import java.net.MalformedURLException;
  10. import java.awt.Event;
  11. import java.awt.Component;
  12. import java.awt.Container;
  13. import java.applet.*;
  14. import java.beans.PropertyVetoException;
  15. import java.beans.PropertyChangeListener;
  16. import java.beans.VetoableChangeListener;
  17. import java.awt.AWTEventMulticaster;
  18. import java.awt.AWTEvent;
  19. import java.awt.event.MouseEvent;
  20. import java.awt.event.ActionEvent;
  21. import java.awt.event.ActionListener;
  22.  
  23. //  Created and implemented by Levi Brown, Symantec Macintosh Internet Tools.
  24. //     02/04/97    LAB    Checked it in
  25. //     05/31/97    LAB    Updated to Java 1.1
  26. //     07/14/97    LAB    Added add/removeNotify for event listener registration.
  27. //                    Removed use of TransparencyTrick and made Lightweight.
  28. //                    Updated version.
  29. //  07/28/97    CAR fixed typo in setStandardFileName and in setDownFileName
  30. //                  marked fields transient as needed
  31. //                  implemented readObject for use during deserialization
  32. //  08/28/97    CAR "erases" images when setters for images are set to null
  33.  
  34. /**
  35.  * This is a button that allows three different states and
  36.  * displays the document with a given URL when clicked.
  37.  * Each button state has its own associated image. Each image is specified
  38.  * by providing the file name or the URL of the file containing the image.
  39.  * The document to show is specified by providing the "LinkURL" of that
  40.  * document.
  41.  * <p>
  42.  * The "standard" state is when the mouse is not over the button.
  43.  * If the standard image is null, the button will be transparent when in the
  44.  * standard state, otherwise the specified image will be displayed.
  45.  * <p>
  46.  * The "over" state is when the mouse cursor is over the button.
  47.  * This state also displays the LinkURL if it is not null.
  48.  * <p>
  49.  * The "down" state is when the mouse button is pressed inside the button.
  50.  * When there is a MOUSE_UP in the button, it will attempt to show the document
  51.  * at the LinkURL unless it is null. This state also displays the
  52.  * LinkURL if it is not null.
  53.  * <p>
  54.  *
  55.  * @version 1.1, July 14, 1997
  56.  * @author Symantec
  57.  */
  58. public class RollOverButton extends Component
  59. {
  60.     /**
  61.      * Constructs a default RollOverButton.
  62.      * It has no associated images nor a LinkURL.
  63.      */
  64.     public RollOverButton()
  65.     {
  66.         standardImage        = null;
  67.         overImage            = null;
  68.         downImage            = null;
  69.         standardFileName    = null;
  70.         overFileName        = null;
  71.         downFileName        = null;
  72.         frame                = null;
  73.         standardURL            = null;
  74.         overURL                = null;
  75.         downURL                = null;
  76.         linkURL                = null;
  77.         isMouseOver            = false;
  78.         isClearFrame        = false;
  79.         isPressed            = false;
  80.         isMouseDrag            = false;
  81.         isCenterMode        = true;
  82.     }
  83.  
  84.     /**
  85.      * Constructs a RollOverButton with an image file name given for each
  86.      * button state.
  87.      * @param Standard the file name of the image to use while the mouse is not over the button
  88.      * @param Over the file name of the image to use while the mouse is over the button
  89.      * @param Down the file name of the image to use while the mouse is over the button and pressed
  90.      * @exception MalformedURLException if a URL cannot be created from any of file names
  91.      */
  92.     public RollOverButton(String standard, String over, String down) throws MalformedURLException
  93.     {
  94.         this();
  95.         try
  96.         {
  97.             setStandardFileName(standard);
  98.             setOverFileName(over);
  99.             setDownFileName(down);
  100.         }
  101.         catch(PropertyVetoException e){}
  102.     }
  103.  
  104.     /**
  105.      * Constructs a RollOverButton with an image file URL given for each
  106.      * button state.
  107.      * @param Standard the URL of the image to use while the mouse is not over the button
  108.      * @param Over the URL of the image to use while the mouse is over the button
  109.      * @param Down the URL of the image to use while the mouse is over the button and pressed
  110.      */
  111.     public RollOverButton(URL standard, URL over, URL down)
  112.     {
  113.         this();
  114.         try
  115.         {
  116.             setStandardURL(standard);
  117.             setOverURL(over);
  118.             setDownURL(down);
  119.         }
  120.         catch(PropertyVetoException e){}
  121.         catch(MalformedURLException e){}
  122.     }
  123.  
  124.     /**
  125.      * Constructs a RollOverButton with an image given for each button state.
  126.      * @param Standard the image to use while the mouse is not over the button
  127.      * @param Over the image to use while the mouse is over the button
  128.      * @param Down the image to use while the mouse is over the button and pressed
  129.      */
  130.     public RollOverButton(Image standard, Image over, Image down)
  131.     {
  132.         this();
  133.         try
  134.         {
  135.             setStandardImage(standard);
  136.             setOverImage(over);
  137.             setDownImage(down);
  138.         }
  139.         catch(PropertyVetoException e){}
  140.     }
  141.  
  142.     /**
  143.      * Sets the file name of the image to display while the mouse is not over
  144.      * the button.
  145.      * @param str the image file name
  146.      * @exception MalformedURLException if a URL cannot be created from the file name
  147.      * @see #getStandardFileName
  148.      * @exception PropertyVetoException
  149.      * if the specified property value is unacceptable
  150.      */
  151.     public void setStandardFileName(String str) throws MalformedURLException, PropertyVetoException
  152.     {
  153.         if(standardFileName != str && (standardFileName == null || !standardFileName.equals(str)))
  154.         {
  155.             String oldValue = standardFileName;
  156.  
  157.             vetos.fireVetoableChange("StandardFileName", oldValue, str);
  158.  
  159.             standardFileName = str;
  160.             if(standardFileName == null)
  161.             {
  162.                 setStandardURL(null);
  163.             }
  164.             else
  165.             {
  166.                 setStandardURL(new URL(standardFileName));
  167.             }
  168.             setStandardURL(new URL(standardFileName));
  169.  
  170.             changes.firePropertyChange("StandardFileName", oldValue, str);
  171.         }
  172.     }
  173.  
  174.     /**
  175.      * Gets the file name of the image to display while the mouse is not over
  176.      * the button.
  177.      * @return the image file name
  178.      * @see #setStandardFileName
  179.      */
  180.     public String getStandardFileName()
  181.     {
  182.         return standardFileName;
  183.     }
  184.  
  185.     /**
  186.      * Sets the file name of the image to display while the mouse is over
  187.      * the button.
  188.      * @param str the image file name
  189.      * @exception MalformedURLException if a URL cannot be created from the file name
  190.      * @see #getOverFileName
  191.      * @exception PropertyVetoException
  192.      * if the specified property value is unacceptable
  193.      */
  194.     public void setOverFileName(String str) throws MalformedURLException, PropertyVetoException
  195.     {
  196.         if(overFileName != str && (overFileName == null || !overFileName.equals(str)))
  197.         {
  198.             String oldValue = overFileName;
  199.  
  200.             vetos.fireVetoableChange("OverFileName", oldValue, str);
  201.  
  202.             overFileName = str;
  203.             if(overFileName == null)
  204.             {
  205.                 setOverURL(null);
  206.             }
  207.             else
  208.             {
  209.                 setOverURL(new URL(overFileName));
  210.             }
  211.  
  212.             changes.firePropertyChange("OverFileName", oldValue, str);
  213.         }
  214.     }
  215.  
  216.     /**
  217.      * Gets the file name of the image to display while the mouse is over
  218.      * the button.
  219.      * @return the image file name
  220.      * @see #setOverFileName
  221.      */
  222.     public String getOverFileName()
  223.     {
  224.         return overFileName;
  225.     }
  226.  
  227.     /**
  228.      * Sets the file name of the image to display while the button is being pressed.
  229.      * @param str the image file name
  230.      * @exception MalformedURLException if a URL cannot be created from the file name
  231.      * @see #getDownFileName
  232.      * @exception PropertyVetoException
  233.      * if the specified property value is unacceptable
  234.      */
  235.     public void setDownFileName(String str) throws MalformedURLException, PropertyVetoException
  236.     {
  237.         if(downFileName != str && (downFileName == null || !downFileName.equals(str)))
  238.         {
  239.             String oldValue = downFileName;
  240.  
  241.             vetos.fireVetoableChange("DownFileName", oldValue, str);
  242.  
  243.             downFileName = str;
  244.             if(downFileName == null)
  245.             {
  246.                 setDownURL(null);
  247.             }
  248.             else
  249.             {
  250.                 setDownURL(new URL(downFileName));
  251.             }
  252.  
  253.             changes.firePropertyChange("DownFileName", oldValue, str);
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Gets the file name of the image to display while the button is being
  259.      * pressed.
  260.      * @return the image file name
  261.      * @see #setDownFileName
  262.      */
  263.     public String getDownFileName()
  264.     {
  265.         return downFileName;
  266.     }
  267.  
  268.     /**
  269.      * Sets the URL of the image to display while the mouse is not over
  270.      * the button.
  271.      * @param aURL the image URL
  272.      * @see #getStandardURL
  273.      * @exception PropertyVetoException
  274.      * if the specified property value is unacceptable
  275.      * @exception MalformedURLException
  276.      * if the given URL is bad
  277.      */
  278.     public void setStandardURL(URL aUrl) throws MalformedURLException, PropertyVetoException
  279.     {
  280.         if(standardURL == null || !standardURL.equals(aUrl))
  281.         {
  282.             URL oldValue = standardURL;
  283.  
  284.             vetos.fireVetoableChange("StandardURL", oldValue, aUrl);
  285.  
  286.             standardURL = aUrl;
  287.             standardFileName = null;
  288.  
  289.             Image loadedImage = null;
  290.             if (aUrl != null)
  291.                 loadedImage= getToolkit().getImage(aUrl);
  292.  
  293.             setStandardImage(loadedImage);
  294.             repaint();
  295.  
  296.             changes.firePropertyChange("StandardURL", oldValue, aUrl);
  297.         }
  298.     }
  299.  
  300.     /**
  301.      * Gets the URL of the image to display while the mouse is not over
  302.      * the button.
  303.      * @return the image URL
  304.      * @see #setStandardURL
  305.      */
  306.     public URL getStandardURL()
  307.     {
  308.         return standardURL;
  309.     }
  310.  
  311.     /**
  312.      * Sets the URL of the image to display while the mouse is over
  313.      * the button.
  314.      * @param aURL the image URL
  315.      * @see #getOverURL
  316.      * @exception PropertyVetoException
  317.      * if the specified property value is unacceptable
  318.      * @exception MalformedURLException
  319.      * if the given URL is bad
  320.      */
  321.     public void setOverURL(URL aUrl) throws MalformedURLException, PropertyVetoException
  322.     {
  323.         if(overURL == null || !overURL.equals(aUrl))
  324.         {
  325.             URL oldValue = overURL;
  326.  
  327.             vetos.fireVetoableChange("OverURL", oldValue, aUrl);
  328.  
  329.             overURL = aUrl;
  330.  
  331.             Image loadedImage = null;
  332.             if (aUrl != null)
  333.                 loadedImage = getToolkit().getImage(aUrl);
  334.  
  335.             setOverImage(loadedImage);
  336.             repaint();
  337.  
  338.             changes.firePropertyChange("OverURL", oldValue, aUrl);
  339.         }
  340.     }
  341.  
  342.     /**
  343.      * Gets the URL of the image to display while the mouse is over
  344.      * the button.
  345.      * @return the image URL
  346.      * @see #setOverURL
  347.      */
  348.     public URL getOverURL()
  349.     {
  350.         return overURL;
  351.     }
  352.  
  353.     /**
  354.      * Sets the URL of the image to display while the button is being pressed.
  355.      * @param aURL the image URL
  356.      * @see #getDownURL
  357.      * @exception PropertyVetoException
  358.      * if the specified property value is unacceptable
  359.      * @exception MalformedURLException
  360.      * if the given URL is bad
  361.      */
  362.     public void setDownURL(URL aUrl) throws MalformedURLException, PropertyVetoException
  363.     {
  364.         if(downURL == null || !downURL.equals(aUrl))
  365.         {
  366.             URL oldValue = downURL;
  367.  
  368.             vetos.fireVetoableChange("DownURL", oldValue, aUrl);
  369.  
  370.             downURL = aUrl;
  371.  
  372.             Image loadedImage = null;
  373.             if (aUrl != null)
  374.                 loadedImage = getToolkit().getImage(aUrl);
  375.  
  376.             setDownImage(loadedImage);
  377.             repaint();
  378.             changes.firePropertyChange("DownURL", oldValue, aUrl);
  379.         }
  380.     }
  381.  
  382.     /**
  383.      * Gets the URL of the image to display while the button is being pressed.
  384.      * @return the image URL
  385.      * @see #setDownURL
  386.      */
  387.     public URL getDownURL()
  388.     {
  389.         return downURL;
  390.     }
  391.  
  392.     /**
  393.      * Sets the image to display while the mouse is not over the button.
  394.      * @param img the image
  395.      * @see #getStandardImage
  396.      * @exception PropertyVetoException
  397.      * if the specified property value is unacceptable
  398.      */
  399.     public void setStandardImage(Image img) throws PropertyVetoException
  400.     {
  401.         if(standardImage == null || !standardImage.equals(img))
  402.         {
  403.             Image oldValue = standardImage;
  404.  
  405.             vetos.fireVetoableChange("StandardImage", oldValue, img);
  406.  
  407.             standardImage    = img;
  408.             setImageHelper(standardImage);
  409.  
  410.             changes.firePropertyChange("StandardImage", oldValue, img);
  411.         }
  412.     }
  413.  
  414.     /**
  415.      * Gets the image displayed while the mouse is not over the button.
  416.      * @return the image
  417.      * @see #setStandardImage
  418.      */
  419.     public Image getStandardImage()
  420.     {
  421.         return standardImage;
  422.     }
  423.  
  424.     /**
  425.      * Sets the image to display while the mouse is over the button.
  426.      * @param img the image
  427.      * @see #getOverImage
  428.      * @exception PropertyVetoException
  429.      * if the specified property value is unacceptable
  430.      */
  431.     public void setOverImage(Image img) throws PropertyVetoException
  432.     {
  433.         if(overImage == null || !overImage.equals(img))
  434.         {
  435.             Image oldValue = overImage;
  436.  
  437.             vetos.fireVetoableChange("OverImage", oldValue, img);
  438.  
  439.             overImage    = img;
  440.             setImageHelper(overImage);
  441.  
  442.             changes.firePropertyChange("OverImage", oldValue, img);
  443.         }
  444.     }
  445.  
  446.     /**
  447.      * Gets the image displayed while the mouse is over the button.
  448.      * @return the image
  449.      * @see #setOverImage
  450.      */
  451.     public Image getOverImage()
  452.     {
  453.         return overImage;
  454.     }
  455.  
  456.     /**
  457.      * Sets the image to display while the button is being pressed.
  458.      * @param img the image
  459.      * @see #getDownImage
  460.      * @exception PropertyVetoException
  461.      * if the specified property value is unacceptable
  462.      */
  463.     public void setDownImage(Image img) throws PropertyVetoException
  464.     {
  465.         if(downImage == null || !downImage.equals(img))
  466.         {
  467.             Image oldValue = downImage;
  468.  
  469.             vetos.fireVetoableChange("DownImage", oldValue, img);
  470.  
  471.             downImage    = img;
  472.             setImageHelper(downImage);
  473.  
  474.             changes.firePropertyChange("DownImage", oldValue, img);
  475.         }
  476.     }
  477.  
  478.     /**
  479.      * Gets the image displayed while the button is being pressed.
  480.      * @return the image
  481.      * @see #setDownImage
  482.      */
  483.     public Image getDownImage()
  484.     {
  485.         return downImage;
  486.     }
  487.  
  488.     /**
  489.      * Sets the flag to erase the background before drawing the button.
  490.      * Not erasing the background often results in a faster, more flicker-free
  491.      * update.
  492.      * @param b if true clear the background before painting, if false then don't
  493.      * @see #isClearFrame
  494.      * @exception PropertyVetoException
  495.      * if the specified property value is unacceptable
  496.      */
  497.     public void setClearFrame(boolean b) throws PropertyVetoException
  498.     {
  499.         Boolean oldValue = new Boolean(isClearFrame);
  500.         Boolean newValue = new Boolean(b);
  501.  
  502.         vetos.fireVetoableChange("ClearFrame", oldValue, newValue);
  503.  
  504.         isClearFrame = b;
  505.  
  506.         changes.firePropertyChange("ClearFrame", oldValue, newValue);
  507.     }
  508.  
  509.     /**
  510.      * Gets the flag that determines if the background should be erased before
  511.      * the button is drawn.
  512.      * @return true if the background will be cleared before painting the button,
  513.      *                    false if it will not be cleared
  514.      * @see #setClearFrame
  515.      */
  516.     public boolean isClearFrame()
  517.     {
  518.         return isClearFrame;
  519.     }
  520.  
  521.     /**
  522.      * @deprecated
  523.      * @see #isClearFrame
  524.      */
  525.     public boolean getClearFrame()
  526.     {
  527.         return isClearFrame();
  528.     }
  529.  
  530.     /**
  531.      * Sets the URL of the document to display on mouse up.
  532.      * @param u the URL of the document to display
  533.      * @see #getURL
  534.      * @exception PropertyVetoException
  535.      * if the specified property value is unacceptable
  536.      */
  537.     public void setURL(URL aUrl) throws PropertyVetoException
  538.     {
  539.         if(linkURL == null || !linkURL.equals(aUrl))
  540.         {
  541.             URL oldValue = linkURL;
  542.  
  543.             vetos.fireVetoableChange("URL", oldValue, aUrl);
  544.  
  545.             linkURL = aUrl;
  546.             context = null;
  547.  
  548.             changes.firePropertyChange("URL", oldValue, aUrl);
  549.         }
  550.     }
  551.  
  552.     /**
  553.      * Gets the URL of the document to display on mouse up.
  554.      * @return the URL of the document to display
  555.      * @see #setURL
  556.      */
  557.     public URL getURL()
  558.     {
  559.         return linkURL;
  560.     }
  561.  
  562.  
  563.     /**
  564.      * Sets the frame specifier for showing a URL document in a browser or applet
  565.      * viewer. It is interpreted as follows:
  566.      * <UL>
  567.      * <DT>"_self"  show document in the current frame</DT>
  568.      * <DT>"_parent"    show document in the parent frame</DT>
  569.      * <DT>"_top"   show document in the topmost frame</DT>
  570.      * <DT>"_blank" show document in a new unnamed toplevel window</DT>
  571.      * <DT>all others   show document in a new toplevel window with the given name</DT>
  572.      * </UL>
  573.      * @param f the new frame specifier
  574.      * @see #getFrame
  575.      * @see #frame
  576.      * @exception PropertyVetoException
  577.      * if the specified property value is unacceptable
  578.      */
  579.     public void setFrame(String f) throws PropertyVetoException
  580.     {
  581.         String oldValue = frame;
  582.  
  583.         vetos.fireVetoableChange("Frame", oldValue, f);
  584.  
  585.         frame = f;
  586.  
  587.         changes.firePropertyChange("Frame", oldValue, f);
  588.     }
  589.  
  590.     /**
  591.      * Gets the frame specifier for showing a URL document in a browser or applet
  592.      * viewer. It is interpreted as follows:
  593.      * <UL>
  594.      * <DT>"_self"  show document in the current frame</DT>
  595.      * <DT>"_parent"    show document in the parent frame</DT>
  596.      * <DT>"_top"   show document in the topmost frame</DT>
  597.      * <DT>"_blank" show document in a new unnamed toplevel window</DT>
  598.      * <DT>all others   show document in a new toplevel window with the given name</DT>
  599.      * </UL>
  600.      * @return the current frame specifier
  601.      * @see #setFrame
  602.      * @see #frame
  603.      */
  604.     public String getFrame()
  605.     {
  606.         return frame;
  607.     }
  608.  
  609.     /**
  610.      * Sets the flag to center the image within the bounds of the button.
  611.      * @param flag true to center the image within the button,
  612.      * false to draw the image at 0,0 relative to the button
  613.      * @see #isCenterMode
  614.      * @exception PropertyVetoException
  615.      * if the specified property value is unacceptable
  616.      */
  617.     public void setCenterMode(boolean flag) throws PropertyVetoException
  618.     {
  619.         if(isCenterMode != flag)
  620.         {
  621.             Boolean oldValue = new Boolean(isCenterMode);
  622.             Boolean newValue = new Boolean(flag);
  623.  
  624.             vetos.fireVetoableChange("CenterMode", oldValue, newValue);
  625.  
  626.             isCenterMode = flag;
  627.             invalidate();
  628.  
  629.             changes.firePropertyChange("CenterMode", oldValue, newValue);
  630.         }
  631.     }
  632.  
  633.     /**
  634.      * Gets the flag that determines whether to center the image within the
  635.      * bounds of the button.
  636.      * @return true if the image will be centered within the button,
  637.      * false if the image will be drawn at 0,0 relative to the button.
  638.      * @see #setCenterMode
  639.      */
  640.     public boolean isCenterMode()
  641.     {
  642.         return isCenterMode;
  643.     }
  644.  
  645.     /**
  646.      * @deprecated
  647.      * @see #isCenterMode
  648.      */
  649.     public boolean getCenterMode()
  650.     {
  651.         return isCenterMode();
  652.     }
  653.  
  654.      /**
  655.      * Paints this component using the given graphics context.
  656.      * This is a standard Java AWT method which typically gets called
  657.      * by the AWT to handle painting this component. It paints this component
  658.      * using the given graphics context. The graphics context clipping region
  659.      * is set to the bounding rectangle of this component and its [0,0]
  660.      * coordinate is this component's top-left corner.
  661.      *
  662.      * @param g the graphics context used for painting
  663.      * @see java.awt.Component#repaint
  664.      * @see #update
  665.      */
  666.     public void paint(Graphics g)
  667.     {
  668.         Dimension dim = size();
  669.  
  670.         int x, y;
  671.         x = y = 0;
  672.  
  673.         if(isPressed)
  674.         {
  675.             if(isMouseOver)
  676.             {
  677.                  //Mouse Down Image
  678.                 if(downImage != null)
  679.                 {
  680.                     if (isCenterMode)
  681.                     {
  682.                         x += (dim.width - downImage.getWidth(this)) / 2;
  683.                         y += (dim.height - downImage.getHeight(this)) / 2;
  684.                     }
  685.                     g.drawImage(downImage, x, y, this);
  686.                 }
  687.             }
  688.             else
  689.             {
  690.                 //RollOver Image
  691.                 if(overImage != null)
  692.                 {
  693.                     if (isCenterMode)
  694.                     {
  695.                         x += (dim.width - overImage.getWidth(this)) / 2;
  696.                         y += (dim.height - overImage.getHeight(this)) / 2;
  697.                     }
  698.                     g.drawImage(overImage, x, y, this);
  699.                 }
  700.             }
  701.         }
  702.         else
  703.         {
  704.             //RollOver Image
  705.             if(isMouseOver && overImage != null)
  706.             {
  707.                 if (isCenterMode)
  708.                 {
  709.                     x += (dim.width - overImage.getWidth(this)) / 2;
  710.                     y += (dim.height - overImage.getHeight(this)) / 2;
  711.                 }
  712.                 g.drawImage(overImage, x, y, this);
  713.             }
  714.             //Standard Image
  715.             else
  716.             {
  717.                  if (standardImage == null)
  718.                  {
  719.                      //Draw the standard state as "Transparent"
  720.                  }
  721.                  else
  722.                  {
  723.                     if (isCenterMode)
  724.                     {
  725.                         x += (dim.width - standardImage.getWidth(this)) / 2;
  726.                         y += (dim.height - standardImage.getHeight(this)) / 2;
  727.                     }
  728.                     g.drawImage(standardImage, x, y, this);
  729.                 }
  730.             }
  731.         }
  732.     }
  733.  
  734.     /**
  735.      * Handles redrawing of this component on the screen.
  736.      * This is a standard Java AWT method which gets called by the Java
  737.      * AWT (repaint()) to handle repainting this component on the screen.
  738.      * The graphics context clipping region is set to the bounding rectangle
  739.      * of this component and its [0,0] coordinate is this component's
  740.      * top-left corner.
  741.      * Typically this method paints the background color to clear the
  742.      * component's drawing space, sets graphics context to be the foreground
  743.      * color, and then calls paint() to draw the component.
  744.      *
  745.      * It is overridden here to add the clear frame feature to this button.
  746.      *
  747.      * @param g the graphics context
  748.      * @see java.awt.Component#repaint
  749.      * @see #paint
  750.      */
  751.     public void update(Graphics g)
  752.     {
  753.         if (isClearFrame)
  754.             super.update(g);
  755.         else
  756.             paint(g);
  757.     }
  758.  
  759.     /**
  760.      * Tells this component that it has been added to a container.
  761.      * This is a standard Java AWT method which gets called by the AWT when
  762.      * this component is added to a container. Typically, it is used to
  763.      * create this component's peer.
  764.      *
  765.      * It has been overridden here to hook-up event listeners.
  766.      *
  767.      * @see #removeNotify
  768.      */
  769.     public synchronized void addNotify()
  770.     {
  771.         super.addNotify();
  772.  
  773.         //Hook up listeners
  774.         if (mouse == null)
  775.         {
  776.             mouse = new Mouse();
  777.             addMouseListener(mouse);
  778.         }
  779.         if (mouseMotion == null)
  780.         {
  781.             mouseMotion = new MouseMtn();
  782.             addMouseMotionListener(mouseMotion);
  783.         }
  784.     }
  785.  
  786.     /**
  787.      * Tells this component that it is being removed from a container.
  788.      * This is a standard Java AWT method which gets called by the AWT when
  789.      * this component is removed from a container. Typically, it is used to
  790.      * destroy the peers of this component and all its subcomponents.
  791.      *
  792.      * It has been overridden here to unhook event listeners.
  793.      *
  794.      * @see #addNotify
  795.      */
  796.     public synchronized void removeNotify()
  797.     {
  798.         //Unhook listeners
  799.         if (mouse != null)
  800.         {
  801.             removeMouseListener(mouse);
  802.             mouse = null;
  803.         }
  804.         if (mouseMotion != null)
  805.         {
  806.             removeMouseMotionListener(mouseMotion);
  807.             mouseMotion = null;
  808.         }
  809.         super.removeNotify();
  810.     }
  811.  
  812.     /**
  813.      * Ensures that this component is laid out properly, as needed.
  814.      * This is a standard Java AWT method which gets called by the AWT to
  815.      * make sure this component and its subcomponents have a valid layout.
  816.      * If this component was made invalid with a call to invalidate(), then
  817.      * it is laid out again.
  818.      *
  819.      * It is overridden here to locate the applet containing this component.
  820.      *
  821.      * @see java.awt.Component#invalidate
  822.      */
  823.     public void validate()
  824.     {
  825.         // On validation, try to find the containing applet.  If we can find
  826.         // it, we don't bother doing the link...
  827.         Container c;
  828.  
  829.         c = getParent();
  830.  
  831.         while (c != null)
  832.         {
  833.             if (c instanceof Applet)
  834.             {
  835.                 setAppletContext(((Applet) c).getAppletContext());
  836.                 break;
  837.             }
  838.  
  839.             c = c.getParent();
  840.         }
  841.     }
  842.  
  843.     /**
  844.      * Returns the recommended dimensions to properly display this component.
  845.      * This is a standard Java AWT method which gets called to determine
  846.      * the recommended size of this component.
  847.      * In this case the recommended size is the minimum dimension needed to
  848.      * encompass the three images that might be displayed.
  849.      *
  850.      * @see #getMinimumSize
  851.      */
  852.     public Dimension getPreferredSize()
  853.     {
  854.         int iWidth, oWidth, dWidth, maxWidth, iHeight, oHeight, dHeight, maxHeight;
  855.         iWidth    = standardImage    == null ? 0 : standardImage.getWidth(this);
  856.         oWidth    = overImage        == null ? 0 : overImage.getWidth(this);
  857.         dWidth    = downImage        == null ? 0 : downImage.getWidth(this);
  858.         iHeight    = standardImage    == null ? 0 : standardImage.getHeight(this);
  859.         oHeight    = overImage        == null ? 0 : overImage.getHeight(this);
  860.         dHeight    = downImage        == null ? 0 : downImage.getHeight(this);
  861.  
  862.         maxWidth    = iWidth >= oWidth ? iWidth : oWidth;
  863.         maxWidth    = maxWidth >= dWidth ? maxWidth : dWidth;
  864.         maxHeight    = iHeight >= oHeight ? iHeight : oHeight;
  865.         maxHeight    = maxHeight >= dHeight ? maxHeight : dHeight;
  866.  
  867.         maxWidth    = maxWidth == 0 ? 10 : maxWidth;
  868.         maxHeight    = maxHeight == 0 ? 10 : maxHeight;
  869.  
  870.         return (new Dimension(maxWidth, maxHeight));
  871.     }
  872.  
  873.     /**
  874.      * Returns the minimum dimensions to properly display this component.
  875.      * This is a standard Java AWT method which gets called to determine
  876.      * the minimum size of this component.
  877.      * In this case the minimum size simply returns the results of
  878.      * a call to getPreferedSize().
  879.      *
  880.      * @see #getPreferredSize
  881.      */
  882.     public Dimension getMinimumSize()
  883.     {
  884.         return getPreferredSize();
  885.     }
  886.  
  887.     /**
  888.      * @deprecated
  889.      * @see #getPreferredSize
  890.      */
  891.     public Dimension preferredSize()
  892.     {
  893.         return getPreferredSize();
  894.     }
  895.  
  896.     /**
  897.      * Sets the command name of the action event fired by this button.
  898.      * @param command The name of the action event command fired by this button
  899.      * @exception PropertyVetoException
  900.      * if the specified property value is unacceptable
  901.      */
  902.     public void setActionCommand(String command) throws PropertyVetoException
  903.     {
  904.         String oldValue = actionCommand;
  905.  
  906.         vetos.fireVetoableChange("ActionCommand", oldValue, command);
  907.         actionCommand = command;
  908.         changes.firePropertyChange("ActionCommand", oldValue, command);
  909.     }
  910.  
  911.     /**
  912.      * @return the command name of the action event fired by this button.
  913.      */
  914.     public String getActionCommand()
  915.     {
  916.         return actionCommand;
  917.     }
  918.  
  919.     /**
  920.      * Adds the specified action listener to receive action events
  921.      * from this button.
  922.      * @param l the action listener
  923.      */
  924.     public synchronized void addActionListener(ActionListener l)
  925.     {
  926.         actionListener = AWTEventMulticaster.add(actionListener, l);
  927.     }
  928.  
  929.     /**
  930.      * Removes the specified action listener so it no longer receives
  931.      * action events from this button.
  932.      * @param l the action listener
  933.      */
  934.     public synchronized void removeActionListener(ActionListener l)
  935.     {
  936.         actionListener = AWTEventMulticaster.remove(actionListener, l);
  937.     }
  938.  
  939.     /**
  940.      * Fire an action event to the listeners
  941.      */
  942.     public void sourceActionEvent()
  943.     {
  944.         if (actionListener != null)
  945.             actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
  946.     }
  947.  
  948.     /**
  949.      * Adds a listener for all event changes.
  950.      * @param listener the listener to add.
  951.      * @see #removePropertyChangeListener
  952.      */
  953.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  954.     {
  955.         changes.addPropertyChangeListener(listener);
  956.     }
  957.  
  958.     /**
  959.      * Removes a listener for all event changes.
  960.      * @param listener the listener to remove.
  961.      * @see #addPropertyChangeListener
  962.      */
  963.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  964.     {
  965.         changes.removePropertyChangeListener(listener);
  966.     }
  967.  
  968.     /**
  969.      * Adds a vetoable listener for all event changes.
  970.      * @param listener the listener to add.
  971.      * @see #removeVetoableChangeListener
  972.      */
  973.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  974.     {
  975.         vetos.addVetoableChangeListener(listener);
  976.     }
  977.  
  978.     /**
  979.      * Removes a vetoable listener for all event changes.
  980.      * @param listener the listener to remove.
  981.      * @see #addVetoableChangeListener
  982.      */
  983.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  984.     {
  985.         vetos.removeVetoableChangeListener(listener);
  986.     }
  987.  
  988.     /**
  989.      * This is the Mouse Event handling innerclass.
  990.      */
  991.     class Mouse extends java.awt.event.MouseAdapter implements java.io.Serializable
  992.     {
  993.         /**
  994.          * Handles the Mouse Pressed events
  995.          * @param e the MouseEvent
  996.          * @see #mouseReleased
  997.          */
  998.         public void mousePressed(MouseEvent e)
  999.         {
  1000.             isPressed = true;
  1001.             //Draw the button
  1002.             repaint();
  1003.         }
  1004.  
  1005.         /**
  1006.          * Handles the Mouse Released events
  1007.          * @param e the MouseEvent
  1008.          * @see #mousePressed
  1009.          */
  1010.         public void mouseReleased(MouseEvent e)
  1011.         {
  1012.             if (isPressed)
  1013.             {
  1014.                 isPressed = false;
  1015.                 //Draw the button.
  1016.                 repaint();
  1017.                 //If the mouse released occured over the button, goto the link, and fire an event.
  1018.                 if(isMouseOver)
  1019.                 {
  1020.                     //Handle going to the linkURL
  1021.                     if (context != null & linkURL != null)
  1022.                     {
  1023.                         if (frame == null || frame.length() == 0)
  1024.                             context.showDocument(linkURL);
  1025.                         else
  1026.                             context.showDocument(linkURL, frame);
  1027.                     }
  1028.                     sourceActionEvent();
  1029.                 }
  1030.             }
  1031.         }
  1032.  
  1033.         /**
  1034.          * Handles the Mouse Entered events
  1035.          * @param e the MouseEvent
  1036.          * @see #mouseExited
  1037.          */
  1038.         public void mouseEntered(MouseEvent e)
  1039.         {
  1040.             isMouseOver = true;
  1041.             //Display the linkURL
  1042.             if (context != null && linkURL != null)
  1043.             {
  1044.                 context.showStatus(linkURL.toString());
  1045.             }
  1046.             //Draw the button
  1047.             repaint();
  1048.         }
  1049.  
  1050.         /**
  1051.          * Handles the Mouse Exited events
  1052.          * @param e the MouseEvent
  1053.          * @see #mouseEntered
  1054.          */
  1055.         public void mouseExited(MouseEvent e)
  1056.         {
  1057.             isMouseOver = false;
  1058.             if (context != null && linkURL != null)
  1059.             {
  1060.                 context.showStatus("");
  1061.             }
  1062.             //Draw the button in the standard state
  1063.             repaint();
  1064.         }
  1065.     }
  1066.  
  1067.     /**
  1068.      * This is the MouseMotion Event handling innerclass.
  1069.      */
  1070.     class MouseMtn implements java.awt.event.MouseMotionListener, java.io.Serializable
  1071.     {
  1072.         /**
  1073.          * Handles the Mouse Moved events
  1074.          * @param e the MouseEvent
  1075.          * @see #mouseDragged
  1076.          */
  1077.         public void mouseMoved(MouseEvent e)
  1078.         {
  1079.             isMouseDrag = false;
  1080.             isPressed = false;
  1081.         }
  1082.  
  1083.         /**
  1084.          * Handles the Mouse Dragged events
  1085.          * @param e the MouseEvent
  1086.          * @see #mouseMoved
  1087.          */
  1088.         public void mouseDragged(MouseEvent e)
  1089.         {
  1090.             isMouseDrag = true;
  1091.         }
  1092.     }
  1093.  
  1094.     /**
  1095.      * A function used to consolidate shared code between the three image setting functions.
  1096.      * @param img the image to set
  1097.      */
  1098.     protected void setImageHelper(Image img)
  1099.     {
  1100.         if (img != null)
  1101.         {
  1102.             MediaTracker tracker;
  1103.  
  1104.             try
  1105.             {
  1106.                 tracker = new MediaTracker(this);
  1107.                 tracker.addImage(img, 0);
  1108.                 tracker.waitForID(0);
  1109.             }
  1110.             catch(InterruptedException e){}
  1111.         }
  1112.         else
  1113.         {
  1114.             repaint();
  1115.         }
  1116.     }
  1117.  
  1118.     /**
  1119.      * Sets the applet context used to view documents.
  1120.      * @param c the new applet context
  1121.      */
  1122.     protected void setAppletContext(AppletContext c)
  1123.     {
  1124.         context = c;
  1125.     }
  1126.  
  1127.     private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
  1128.         in.defaultReadObject();
  1129.  
  1130.         if(standardURL != null) {
  1131.             standardImage = getToolkit().getImage(standardURL);
  1132.             if (standardImage != null)
  1133.             {
  1134.                 setImageHelper(standardImage);
  1135.                 repaint();
  1136.             }
  1137.         }
  1138.  
  1139.         if (overURL != null) {
  1140.             overImage = getToolkit().getImage(overURL);
  1141.             if (overImage != null)
  1142.             {
  1143.                 setImageHelper(overImage);
  1144.                 repaint();
  1145.             }
  1146.         }
  1147.  
  1148.         if (downURL != null) {
  1149.             downImage = getToolkit().getImage(downURL);
  1150.             if (downImage != null)
  1151.             {
  1152.                 setImageHelper(downImage);
  1153.                 repaint();
  1154.             }
  1155.         }
  1156.  
  1157.     }
  1158.  
  1159.     /**
  1160.      * The image displayed while the mouse is not over the button.
  1161.      * If this is null, the button will be invisible in this state.
  1162.      */
  1163.     transient protected Image standardImage;
  1164.     /**
  1165.      * The image displayed while the mouse is over the button.
  1166.      * If this is null, the StandardImage will be used.
  1167.      * If that is null, the button will be invisible in this state.
  1168.      */
  1169.     transient protected Image overImage;
  1170.     /**
  1171.      * The image displayed while the mouse is pressed down inside the button.
  1172.      * If this is null, no drawing takes place.
  1173.      */
  1174.     transient protected Image downImage;
  1175.     /**
  1176.      * The file name of the image to display while the mouse is not over the button.
  1177.      */
  1178.     protected String standardFileName;
  1179.     /**
  1180.      * The file name of the image to display while the mouse is over the button.
  1181.      */
  1182.     protected String overFileName;
  1183.     /**
  1184.      * The file name of the image to display while the mouse is over the button and pressed.
  1185.      */
  1186.     protected String downFileName;
  1187.     /**
  1188.      * The frame specifier for showing a URL document in a browser or applet
  1189.      * viewer. It is interpreted as follows:
  1190.      * <UL>
  1191.      * <DT>"_self"  show document in the current frame</DT>
  1192.      * <DT>"_parent"    show document in the parent frame</DT>
  1193.      * <DT>"_top"   show document in the topmost frame</DT>
  1194.      * <DT>"_blank" show document in a new unnamed toplevel window</DT>
  1195.      * <DT>all others   show document in a new toplevel window with the given name</DT>
  1196.      * </UL>
  1197.      */
  1198.     protected String frame;
  1199.     /**
  1200.      * The URL of the image to use in while the mouse is not over the button.
  1201.      */
  1202.     protected URL standardURL;
  1203.     /**
  1204.      * The URL of the image to use while the mouse is over the button.
  1205.      */
  1206.     protected URL overURL;
  1207.     /**
  1208.      * The URL of the image to use while the mouse is over the button and pressed.
  1209.      */
  1210.     protected URL downURL;
  1211.     /**
  1212.      * The URL of the document to show after the button has been pressed.
  1213.      */
  1214.     protected URL linkURL;
  1215.     /**
  1216.      * If true the image will be centered within the bounds of the
  1217.      * button. If false the image is drawn at
  1218.      * 0,0 relative to the bounds of the button.
  1219.      */
  1220.     protected boolean isCenterMode;
  1221.     /**
  1222.      * True if the mouse is over the button.
  1223.      */
  1224.     transient protected boolean isMouseOver;
  1225.     /**
  1226.      * If true the frame is cleared in between drawing
  1227.      * different button states.
  1228.      */
  1229.     protected boolean isClearFrame;
  1230.     /**
  1231.      * True if the mouse button is being pressed.
  1232.      */
  1233.     transient protected boolean isPressed;
  1234.     /**
  1235.      * True if the mouse is being dragged in the button.
  1236.      */
  1237.     transient protected boolean isMouseDrag;
  1238.     /**
  1239.      * The applet context that shows the document.
  1240.      */
  1241.     transient protected AppletContext context;
  1242.  
  1243.     String actionCommand;
  1244.     ActionListener actionListener = null;
  1245.  
  1246.     private Mouse            mouse        = null;
  1247.     private MouseMtn        mouseMotion    = null;
  1248.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  1249.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  1250. }
  1251.  
  1252.